import java.util.ArrayList;
import java.util.Set;


/**
 * Class that creates the score-card.
 * @author Lucatero
 *
 */
public class ScoreCard
{
	public int _highestScore;
	public ArrayList<ScoreCategory> _categories;
	public ArrayList<ScoreCategory> _scoredCategories;
	public int _chanceDieDeduction;
	private int _totalScore;
	private int _remainingReRolls;
	
	/**
	 * Initialize Card.
	 */
	public ScoreCard()
	{
		_categories = new ArrayList<ScoreCategory>();
		_scoredCategories = new ArrayList<ScoreCategory>();
		_remainingReRolls = 7;
		initializeCategories();
	}
	
	/**
	 * Initialize the score categories
	 */
	private void initializeCategories()
	{
		_categories.clear();
		_categories.add(ScoreCategory.aces);
		_categories.add(ScoreCategory.deuces);
		_categories.add(ScoreCategory.treys);
		_categories.add(ScoreCategory.fours);
		_categories.add(ScoreCategory.fives);
		_categories.add(ScoreCategory.sixes);
		_categories.add(ScoreCategory.twoPairSameColor);
		_categories.add(ScoreCategory.threeOfAKind);
		_categories.add(ScoreCategory.straight);
		_categories.add(ScoreCategory.flush);
		_categories.add(ScoreCategory.fullHouse);
		_categories.add(ScoreCategory.fullHouseSameColor);
		_categories.add(ScoreCategory.fourOfAKind);
		_categories.add(ScoreCategory.twoColorsOnly);
		_categories.add(ScoreCategory.cpc);
	}

	/**
	 * Sets the highest score.
	 * @param newHighScore
	 */
	public void setHighestScore(int newHighScore) 
	{
		_highestScore = newHighScore;	
	}
	
	/**
	 * Returns the highest score.
	 * @return High Score
	 */
	public int getHighestScore() 
	{
		return _highestScore;	
	}
	
	/**
	 * Clear card.
	 */
	public void clear() 
	{
		initializeCategories();
		_scoredCategories.clear();
		_chanceDieDeduction = 0;
		_totalScore = 0;
	}
		
	/**
	 * Return chance deductions cost.
	 */
	public int getChanceDieDeduction() 
	{
		// TODO : to implement
		return _chanceDieDeduction;	
	}
	
	/**
	 * Return re-roll bonuses.
	 * @return Bonus
	 */
	public int getReRollBonus() 
	{
		// TODO : to implement
		return _remainingReRolls;	
	}
	
	/**
	 * This will sum all values, reroll bonuses, and chance die deductions of all Scores. It will then return them tied together as a single value.
	 * <!-- begin-user-doc -->
	 * <!--  end-user-doc  -->
	 * @generated
	 * @ordered
	 */
	public int getTotalScore() 
	{
		int totalScore;
		
		if(isComplete())
			totalScore = _totalScore - _chanceDieDeduction + _remainingReRolls;
		else
			totalScore = _totalScore;
		// TODO : to implement
		return totalScore;	
	}
	
	/**
	 * Return remaining re-rolls.
	 * @return remaining re-rolls.
	 */
	public int getRemainingReRolls()
	{
		return _remainingReRolls;
	}
	
	/**
	 * Decrement re-rolls.
	 */
	public void decrementRemainingReRolls()
	{
		_remainingReRolls--;
	}
	
	/**
	 * Used to call scoring
	 * @param scoreCategory
	 * @param currentRoll
	 * @param indexesForScoring
	 * @return
	 */
	public int score(ScoreCategory scoreCategory, Die[] currentRoll, ArrayList<Integer> indexesForScoring) 
	{
		ArrayList<Integer> scoringDie = new ArrayList<Integer>();
		
		for(int index : indexesForScoring)
		{
			scoringDie.add(currentRoll[index].getNumber().getValue());
			
			if(index == 5)
				_chanceDieDeduction++;
			if(index == 6)
				_chanceDieDeduction+=2;
			if(index == 7)
				_chanceDieDeduction+=4;
		}
		
		_categories.remove(scoreCategory);
		int result = scoreCategory.score(scoringDie);
		_totalScore += result;
		_scoredCategories.add(scoreCategory);
		
		return result;
	}
	
	/**
	 * Informs if the scorecard is complete.
	 * @return
	 */
	public boolean isComplete()
	{
		return (_categories.isEmpty());
	}
	
	/**
	 * Returns the unscored categories.
	 * @return unscored categories.
	 */
	public ArrayList<ScoreCategory> getUnscoredCategories()
	{
		return _categories;
	}
	
	/**
	 * Returns scored categories.
	 * @return scored categories.
	 */
	public ArrayList<ScoreCategory> getScoredCategories()
	{
		return _scoredCategories;
	}
}
